package com.cmnit.analysis.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

/**
 * HF
 * 2020-06-07 16:41
 * 德鲁伊连接池
 */
public class DataSourceUtil implements Serializable {

    // 读取JDBC连接池
    public static DataSource dataSource = null;
    public static String jdbcUrl = ConfigurationManager.getProperty("vertica.url");
    public static String jdbcUser = ConfigurationManager.getProperty("vertica.username");
    public static String jdbcPassword = ConfigurationManager.getProperty("vertica.password");
    public static String jdbcDriver = ConfigurationManager.getProperty("vertica.driver");

    static {
        try {
            Properties props = new Properties();
            props.setProperty("url", jdbcUrl);
            props.setProperty("username", jdbcUser);
            props.setProperty("password", jdbcPassword);
            props.setProperty("driverClassName", jdbcDriver);
            props.setProperty("initialSize", "5"); // 初始化大小
            props.setProperty("maxActive", "300"); // 最大连接,可能要调整
            props.setProperty("minIdle", "8"); // 最小连接,可能要调整
            props.setProperty("maxWait", "60000"); // 等待时长
            props.setProperty("timeBetweenEvictionRunsMillis", "2000"); // 配置多久进行一次检测,检测需要关闭的连接 单位毫秒
            props.setProperty("minEvictableIdleTimeMillis", "600000"); // 配置连接在连接池中最小生存时间 单位毫秒
            props.setProperty("maxEvictableIdleTimeMillis", "900000"); // 配置连接在连接池中最大生存时间 单位毫秒
            props.setProperty("connectionErrorRetryAttempts", "3"); // 超时时重连的次数
            props.setProperty("remove-abandoned", "false"); // false时候连接出问题才会重连
            props.setProperty("breakAfterAcquireFailure", "false"); // 获取连接失败时,一直重试
            props.setProperty("timeBetweenConnectErrorMillis", "300000"); // 失败获取连接的时间间隔
            props.setProperty("validationQuery", "select 1");
            props.setProperty("testWhileIdle", "true");
            props.setProperty("testOnBorrow", "false");
            props.setProperty("testOnReturn", "false");
            props.setProperty("keepAlive", "true");
            props.setProperty("phyMaxUseCount", "100000");

            //根据上述配置，生成德鲁伊连接池
            dataSource = DruidDataSourceFactory.createDataSource(props);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 提供获取连接的方法
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    /**
     * 关闭连接
     *
     * @param resultSet         结果集
     * @param preparedStatement pstm
     * @param connection        connect
     */
    public static void closeResource(ResultSet resultSet, PreparedStatement preparedStatement, Connection connection) {
        // 关闭结果集
        closeResultSet(resultSet);
        // 关闭语句执行者
        closePrepareStatement(preparedStatement);
        // 关闭连接
        closeConnection(connection);
    }

    /**
     * 关闭连接
     *
     * @param preparedStatement pstm
     * @param connection        connect
     */
    public static void closeResource(PreparedStatement preparedStatement, Connection connection) {
        // 关闭语句执行者
        closePrepareStatement(preparedStatement);
        // 关闭连接
        closeConnection(connection);
    }

    /**
     * 关闭连接
     *
     * @param connection connect
     */
    public static void closeConnection(Connection connection) {
        try {
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭连接
     *
     * @param preparedStatement pstm
     */
    public static void closePrepareStatement(PreparedStatement preparedStatement) {
        try {
            if (preparedStatement != null) {
                preparedStatement.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭连接
     *
     * @param resultSet result
     */
    public static void closeResultSet(ResultSet resultSet) {
        try {
            if (resultSet != null) {
                resultSet.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
